﻿using Assets.Script.HelpSystem.AtkSystem.Base;
using Assets.Script.Human.Player;
using Assets.Script.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

namespace Assets.Script.HelpSystem.AtkSystem
{
    public partial class AtkWay
    {
        protected bool inAttack = false;
        /// <summary>
        /// 子弹实体，在初始化时自动加载
        /// </summary>
        protected GameObject bullet;
        protected bool canAttack=true;

        protected Animator animator;
        protected Timer atkTimer;
        protected PlayerBody playerBody;
        /// <summary>
        /// 播放攻击动画到子弹生成的等待时间
        /// </summary>
        protected float atkWaitTime = 0;
        protected AtkInfo atkInfo;//攻击信息
        protected Dictionary<Type, int> bulletEffectLevel;//子弹效果
        private int index;
        protected float coolTime = 1f;//冷却时间
        #region 弹道
        /// <summary>
        /// 能否多弹道
        /// </summary>
        protected bool canMultiple = true;
        /// <summary>
        /// 每个方向的攻击角度
        /// </summary>
        protected float attackDirAngleRange = 30f;
        /// <summary>
        /// 各各方向的弹道数量
        /// </summary>
        protected AttackDir attackDir;

        protected BulletData bulletData;
        #endregion




        protected float dmg;

        public AtkWay(PlayerBody playerBody,AtkInfo atkInfo, Dictionary<Type, int> bulletEffectLevel,int index)
        {
            this.playerBody = playerBody;
            this.atkInfo = atkInfo;
            this.bulletEffectLevel = bulletEffectLevel;
            this.index = index;
            animator = playerBody.animator;
            attackDir = playerBody.PlayerData.AttackDir;
            bullet = Resources.Load<GameObject>(ResourcePath.BulletFilePath + atkInfo.BullteName);
            //设置需要计算的数据
            SetData(playerBody.Id);
            //添加监听
            EventManager.Listen(EventName.Player.DataChange, SetData);
        }

        protected virtual void SetData(params object[] o)
        {
            dmg = playerBody.PlayerData.BulletData.Atk;
            bulletData = new BulletData(playerBody.PlayerData.BulletData);
            coolTime = new BaseData(atkInfo.ColdTime)+playerBody.PlayerData.SkillsCD;
            
        }

        ~AtkWay()
        {
            EventManager.UnListen(EventName.Player.DataChange, SetData);
        }


        #region 供外界调用
        public void AttackStart()
        {
            if (inAttack)
            {
                return;
            }
            inAttack = true;
            AttackStart_m();
        }

        public void AttackEnd()
        {
            if (!inAttack)
            {
                return;
            }
            inAttack = false;
            AttackEnd_m();
        }

        public virtual void AttackInterrupt()
        {
            inAttack = false;
            AttackEnd_m();
            if (atkTimer!=null)
            {
                atkTimer.Stop();
            }
        }

        /// <summary>
        /// 每帧动作(即使不在攻击也会调用)
        /// </summary>
        public void Update()
        {
            UpdateAlways();
            if (inAttack)
            {
                UpdateInAttack();
            }
        }

        #endregion

        /// <summary>
        ///调用攻击动作,扣蓝
        /// </summary>
        protected  void Attack_Invoke()
        {
            if (canAttack&&playerBody.UseMana(atkInfo.NeedMana))
            {
                Attack_Normal();
                canAttack = false;
                EventManager.Broadcast(EventName.Player.AttackState, playerBody.Id, true, index);
                new Timer(coolTime, false, TimeData.One, () => {
                    canAttack = true;
                }).Start();
            }
        }



        /// <summary>
        /// 每帧动作(即使不在攻击也会调用)
        /// </summary>
        protected virtual void UpdateAlways()
        {

        }

        /// <summary>
        /// 在攻击时会每帧调用
        /// </summary>
        protected virtual void UpdateInAttack()
        {

        }



        /// <summary>
        ///  攻击开始动作
        /// </summary>
        protected virtual void AttackStart_m()
        {

        }

        /// <summary>
        /// 攻击结束动作
        /// </summary>
        protected virtual void AttackEnd_m()
        {
            
        }



        /// <summary>
        /// 攻击动作，制作子弹,控制弹道,播放音效等，
        /// </summary>
        protected virtual void Attack_Normal()
        {
            //animator.SetTrigger("atkStart");
            atkTimer = new Timer(atkWaitTime, false, TimeData.One, () =>
            {
                if (attackDir.forward > 0)
                    CreateBulletWithDirAndNum(playerBody.fire_forward, ref attackDir.forward);
                if (attackDir.back > 0)
                    CreateBulletWithDirAndNum(playerBody.fire_back, ref attackDir.back);
                if (attackDir.left > 0)
                    CreateBulletWithDirAndNum(playerBody.fire_left, ref attackDir.left);
                if (attackDir.rigt > 0)
                    CreateBulletWithDirAndNum(playerBody.fire_right, ref attackDir.rigt);
            });
            atkTimer.Start();
        }

        /// <summary>
        /// 制作子弹
        /// </summary>
        /// <returns></returns>
        protected virtual GameObject CreateBullet(Transform orgin)
        {
            var clo = GameObject.Instantiate(bullet);
            clo.GetComponentInChildren<PlayerBulletBodyBase>().Init(playerBody.Id,ref dmg, orgin.position, bulletData, TimeData.One, bulletEffectLevel);
            clo.transform.rotation = orgin.rotation;
            clo.transform.position = orgin.position;
            clo.transform.localScale = bulletData.BulletScale * Vector3.one;
            return clo;
        }

        /// <summary>
        /// 创建子弹
        /// </summary>
        /// <param name="orgin"></param>
        /// <param name="num"></param>
        protected virtual void CreateBulletWithDirAndNum(Transform orgin,ref int num)
        {
            if (canMultiple)
            {
                if (num == 1)
                {
                    CreateBullet(orgin);
                }
                else if (num == 2)
                {
                    //并排发射处理
                    var clo1 = CreateBullet(orgin);
                    clo1.transform.Translate(new Vector3(-0.4f, 0,0 ), Space.Self);
                    var clo2 = CreateBullet(orgin);
                    clo2.transform.Translate(new Vector3(0.4f, 0, 0), Space.Self);
                }
                else
                {
                    //均匀±15°发射处理
                    var perAngle = attackDirAngleRange / (float)(num - 1f);
                    for (int i = 0; i < num; i++)
                    {
                        var clo = CreateBullet(orgin);
                        clo.transform.Rotate(0, -15f + i * perAngle, 0);
                    }
                }
            }
            else
            {
                CreateBullet(orgin);
            }
        }

    }
}
